package info.batcloud.fanli.core.service.impl;

import com.ctospace.archit.common.pagination.Paging;
import info.batcloud.fanli.core.dto.WalletFlowDetailDTO;
import info.batcloud.fanli.core.entity.UserWithdraw;
import info.batcloud.fanli.core.entity.WalletFlowDetail;
import info.batcloud.fanli.core.enums.EnumTitle;
import info.batcloud.fanli.core.enums.WalletFlowDetailType;
import info.batcloud.fanli.core.helper.PagingHelper;
import info.batcloud.fanli.core.repository.UserWithdrawRepository;
import info.batcloud.fanli.core.repository.WalletFlowDetailRepository;
import info.batcloud.fanli.core.service.WalletFlowDetailService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class WalletFlowDetailServiceImpl implements WalletFlowDetailService {

    @Inject
    private WalletFlowDetailRepository walletFlowDetailRepository;
    @Inject
    private UserWithdrawRepository userWithdrawRepository;

    @Override
    public Paging<WalletFlowDetailDTO> search(SearchParam param) {
        Specification<WalletFlowDetail> specification = (root, query, cb) -> {
            Predicate predicate = cb.conjunction();
            List<Expression<Boolean>> expressions = predicate.getExpressions();
            if (param.getUserId() != null) {
                expressions.add(cb.equal(root.get("userId"), param.getUserId()));
            }
            if (param.getType() != null) {
                expressions.add(cb.equal(root.get("type"), param.getType()));
            }
            if (param.getValueType() != null) {
                expressions.add(cb.equal(root.get("valueType"), param.getValueType()));
            }
            return predicate;
        };
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        Pageable pageable = new PageRequest(param.getPage() - 1,
                param.getPageSize(), sort);
        Page<WalletFlowDetail> page = walletFlowDetailRepository.findAll(specification, pageable);
        //处理withdraw的状态显示
        List<Long> withdrawDetailIds = page.getContent().stream().filter(detail -> detail.getType()
                == WalletFlowDetailType.USER_WITHDRAW).map(detail -> detail.getId())
                .collect(Collectors.toList());
        List<UserWithdraw> userWithdraws = userWithdrawRepository.findByWalletFlowDetailIdIn(withdrawDetailIds);
        Map<Long, EnumTitle> userWithdrawStatusMapByDetailId = new HashMap<>();
        Map<Long, Long> relationIdMapByDetailId = new HashMap<>();
//        Map<Long, List<String>> detailInfoListMap = new HashMap<>();
        for (UserWithdraw userWithdraw : userWithdraws) {
            userWithdrawStatusMapByDetailId.put(userWithdraw.getWalletFlowDetailId(), userWithdraw.getStatus());
            relationIdMapByDetailId.put(userWithdraw.getWalletFlowDetailId(), userWithdraw.getId());
        }
        return PagingHelper.of(page, detail -> {
            WalletFlowDetailDTO dto = new WalletFlowDetailDTO();
            BeanUtils.copyProperties(detail, dto);
            dto.setStatus(userWithdrawStatusMapByDetailId.get(detail.getId()));
            dto.setRelationId(relationIdMapByDetailId.get(detail.getId()));
            return dto;
        }, param.getPage(), param.getPageSize());
    }
}
